package com.dongzili.common.mybatisplus;

import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import java.util.concurrent.ConcurrentHashMap;

public class MybatisPlusUtil {
    /**
     * 服务缓存
     */
    private static final ConcurrentHashMap<Class<?>, IService<?>> SERVICE_CACHE = new ConcurrentHashMap<>();

    /**
     * Mapper缓存
     */
    private static final ConcurrentHashMap<Class<?>, BaseMapper<?>> MAPPER_CACHE = new ConcurrentHashMap<>();

    /**
     * 获取Service（带缓存）
     */
    @SuppressWarnings("unchecked")
    public static <T> IService<T> getService(final Class<T> t) {
        try {
            DS ds = t.getAnnotation(DS.class);
            if (ds != null){
                DynamicDataSourceContextHolder.push(ds.value());
            }else{
                DynamicDataSourceContextHolder.push("main");
            }
            return (IService<T>) SERVICE_CACHE.computeIfAbsent(t, k -> {
                String beanName = getBeanName(t) + "AutoServiceImpl";
                return SpringUtil.getBean(beanName);
            });
        } catch (NoSuchBeanDefinitionException e) {
            throw new RuntimeException("未找到对应的Service实现: " + getBeanName(t) + "AutoServiceImpl", e);
        }
    }

    /**
     * 获取Mapper（带缓存）
     */
    @SuppressWarnings("unchecked")
    public static <T> BaseMapper<T> getMapper(final Class<T> t) {
        try {
            DS ds = t.getAnnotation(DS.class);
            if (ds != null){
                DynamicDataSourceContextHolder.push(ds.value());
            }else{
                DynamicDataSourceContextHolder.push("main");
            }
            return (BaseMapper<T>) MAPPER_CACHE.computeIfAbsent(t, k -> {
                String beanName = getBeanName(t) + "AutoMapper";
                return SpringUtil.getBean(beanName);
            });
        } catch (NoSuchBeanDefinitionException e) {
            throw new RuntimeException("未找到对应的Mapper: " + getBeanName(t) + "AutoMapper", e);
        }
    }

    /**
     * 获取bean名称
     */
    private static <T> String getBeanName(final Class<T> t) {
        return t.getSimpleName().substring(0, 1).toLowerCase() + t.getSimpleName().substring(1);
    }
}